package spring.chatroom.java_chatroom.server.imp;

import cn.hutool.core.annotation.Link;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import spring.chatroom.java_chatroom.common.constant.Constants;
import spring.chatroom.java_chatroom.mapper.ChatInfoMapper;
import spring.chatroom.java_chatroom.pojo.model.ChatInfo;
import spring.chatroom.java_chatroom.pojo.model.MsgInfo;
import spring.chatroom.java_chatroom.server.SaveFiles;

import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.UUID;

@Slf4j
@Service
public class SaveFilesImp implements SaveFiles {

    @Autowired
    Constants constants;

    @Autowired
    ChatInfoMapper chatInfoMapper;

    //实例化先于注入执行，你想要使用注入的constants 需要使用PostConstruct 来初始化 我实例化之后不能注入吗
    //因为类的创建在DI注入之前，所以在创建PATH_ARR时会使用到Constants，而这时并没有到注入他的时候，所以需要改变下
    public List<Set<String>> SUFFIXS = null;

    public String[] PATH_ARR = null;

    @PostConstruct
    public void init() {
        SUFFIXS  = List.of(constants.picSet, constants.videoSet, constants.documentSet);
        PATH_ARR = new String[]{constants.localPicPath, constants.localVideoPath, constants.localDocPath, constants.localOthersPath};
    }

    @Override
    public List<MsgInfo> saveToDB(List<String> list, MsgInfo msgInfo) {
        List<MsgInfo> msgInfoList = new LinkedList<>();
        for(String str : list) {

            ChatInfo c = new ChatInfo();
            BeanUtils.copyProperties(msgInfo, c);
            c.setContent(str);

            chatInfoMapper.insertInfo(c);

            msgInfo.setId(c.getId());
            msgInfo.setContent(str);
            log.info("消息数据库中数据 {}", msgInfo);

            msgInfoList.add(new MsgInfo(msgInfo));
        }
        return msgInfoList;
    }

    @Override
    public List<String> saveFiles(List<MultipartFile> file) {
        List<String> PathName = new LinkedList<>();
        for (MultipartFile fileItem : file) {
            try{
                String path = saveFile(fileItem);
                log.info("储存的文件路径 {}", path);
                PathName.add(path);
            }catch (Exception e){
                log.error(e.getMessage(), e);
            }
        }
        return PathName;
    }

    /**
     * 对于文件的操作，应该是消息中有这个文件的地址，在前端读取时，发现这时一个文件地址
     * 那么就像后端请求这个文件，并且修改页面消息的渲染
     */

    public String saveFile(MultipartFile file) {
        String picName = file.getOriginalFilename();

        assert picName != null;

        //获取到后缀 名字
        int poi = picName.lastIndexOf(".");

        String suffix = picName.substring(poi);

        String localPath = "";
        String prefix = "";

        //根据后缀找到对应的文件储存前缀后储存地址
        for(int i = 0; i < 3; i++){
            Set<String> suffixSet = SUFFIXS.get(i);
            if(suffixSet.contains(suffix)){
                localPath = PATH_ARR[i];
                prefix = constants.FILE_PREFIX[i];
            }
        }

        if (suffix.isEmpty()) {
            return "不支持的文件类型";
        }

        if(localPath.isEmpty()){
//            throw new RuntimeException("不支持的文件格式" + prefix);
            //那么给他储存到others中
            prefix = constants.FILE_PREFIX[3];
            localPath = PATH_ARR[3];
        }

        //给改为个新名字储存
        StringBuilder saveName = new StringBuilder();

        saveName.append(UUID.randomUUID().toString().substring(0, 10)).append(LocalDateTime.now().format(DateTimeFormatter.ofPattern("-yyyy-MM-dd-HH-mm-ss"))).append(suffix);

        File dir = new File(localPath);
        //创建这个目录
        if (!dir.exists()) {
            dir.mkdirs();
        }

        return savaToLocal(dir, file, saveName, prefix);
    }

    private String savaToLocal(File dir, MultipartFile file, StringBuilder saveName, String prefix) {
        File dest = new File(dir, saveName.toString());

        try {
            //返回的是相对路径
            file.transferTo(dest);
            //放回储存到硬盘中的url
            log.info("储存的路径 {}", dir.getAbsolutePath() + "\\" + saveName.toString());
            //因为使用的资源映射，那么我就只需要储存图片就好了
            return prefix + saveName.toString();
        } catch (IOException e) {
            log.error("save pic error", e);
            throw new RuntimeException(e);
        }
    }
}
